﻿using System;
using System.Collections.Generic;
using System.Xml;
using UnityEngine;

namespace EditorFramework
{
    public class XMLGUI
    {
        private List<XMLGUIBase> mXMLGUIList = new List<XMLGUIBase>();
        private Dictionary<string, XMLGUIBase> mGUIBaseDict = new Dictionary<string, XMLGUIBase>();

        public T GetGUIBaseByID<T>(string id) where T : XMLGUIBase
        {
            XMLGUIBase t = default;
            if(mGUIBaseDict.TryGetValue(id, out t))
            {
                return t as T;
            }
            else
            {
                return default;
            }
        }

        private Dictionary<string, Func<XMLGUIBase>> mGUIBaseFactoryDict = new Dictionary<string, Func<XMLGUIBase>>()
        {
            { "Label", () => new XMLGUILabel() },
            { "LayoutLabel", () => new XMLGUILayoutLabel() },
            { "TextField", () => new XMLGUITextField() },
            { "TextArea", () => new XMLGUITextArea() },
            { "Button", () => new XMLGUIButton() },
            { "LayoutButton", () => new XMLGUILayoutButton() },
            { "LayoutHorizontal", () => new XMLGUILayoutHorizontal() },
            { "LayoutVertical", () => new XMLGUILayoutVertical() },
        };
        
        public void ReadXML(string xml)
        {
            var doc = new XmlDocument();
            doc.LoadXml(xml);

            var rootNode = doc.SelectSingleNode("GUI"); // 获取根节点
            
            ChildElements2GUIBases(rootNode as XmlElement, this);
            
        }

        public void ChildElements2GUIBases(XmlElement rootNode, XMLGUI rooXmlgui)
        {
            foreach (var rootNodeChildNodeObj in rootNode.ChildNodes)
            {
                var rootNodeChildNode = rootNodeChildNodeObj as XmlElement;

                Func<XMLGUIBase> guiBaseFactory = null;
                if(rootNodeChildNode != null && mGUIBaseFactoryDict.TryGetValue(rootNodeChildNode.Name, out guiBaseFactory))
                {
                    var guiBase = guiBaseFactory.Invoke();
                    guiBase.ParseXML(rootNodeChildNode, rooXmlgui);
                    AddGuiBase(guiBase, rooXmlgui);
                }
            }
        }

        void AddGuiBase(XMLGUIBase guiBase, XMLGUI rooXmlgui)
        {
            mXMLGUIList.Add(guiBase);
            if (!string.IsNullOrEmpty(guiBase.Id))
            {
                mGUIBaseDict.Add(guiBase.Id, guiBase);

                if (rooXmlgui != this)
                {
                    rooXmlgui.mGUIBaseDict.Add(guiBase.Id, guiBase);
                }
            }
        }

        public void Draw()
        {
            foreach (var guiBase in mXMLGUIList)
            {
                guiBase.Draw();
            }
        }
    }
}